﻿//------------------------------------------------------------------------------
// Base repository created by Kevin Wang
// 
//------------------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Data.Objects;
using System.Globalization;
using System.Data.Entity.Design.PluralizationServices;
using System.Data.Entity;
using System.Data;
using System.Data.Entity.Infrastructure;
using $safeprojectname$.Data;

namespace $safeprojectname$.Repositories
{
    public class Repository<T> : IRepository<T> where T : class
    {
        public Repository()
        {
            _context = new ModelContainer();
        }

        private ModelContainer _context;
        private readonly PluralizationService _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));

        public ModelContainer DataContext
        {
            get { return _context ?? (_context = new ModelContainer()); }
        }

        public IQueryable<T> GetQuery<T>()
        {
            var entityName = string.Format("{0}.{1}", ((IObjectContextAdapter)_context).ObjectContext.DefaultContainerName, _pluralizer.Pluralize(typeof(T).Name));
            return ((IObjectContextAdapter)_context).ObjectContext.CreateQuery<T>(entityName);
        }

        public virtual T Find(int id)
        {
            throw new NotImplementedException();
        }

        public virtual T Find(Expression<Func<T, bool>> where)
        {
            return GetQuery<T>().FirstOrDefault<T>(where);
        }

        public virtual IEnumerable<T> FindList(Expression<Func<T, bool>> where)
        {
            return GetQuery<T>().Where<T>(where);
        }

        public virtual IEnumerable<T> FindAll()
        {
            return GetQuery<T>();
        }

        public virtual void Add(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            _context.Set<T>().Add(entity);
        }

        public virtual void Attach(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }

            _context.Set<T>().Attach(entity);
        }

        public virtual void Update(T entity)
        {
            if (entity != null)
            {
                Attach(entity);
                _context.Entry(entity).State = EntityState.Modified;
                SaveChanges();
            }
        }

        public virtual void Delete(T entity)
        {
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            _context.Set<T>().Remove(entity);
        }

        public virtual T Create(T entity)
        {
            Add(entity);
            _context.SaveChanges();
            return entity;
        }

        public int Count()
        {
            return GetQuery<T>().Count();
        }

        public int Count(Expression<Func<T, bool>> where)
        {
            return GetQuery<T>().Count(where);
        }

        public void SaveChanges()
        {
            _context.SaveChanges();
        }

    }

}
